home *** CD-ROM | disk | FTP | other *** search
- *********************************************************************
- This article is being presented through the *StarBoard* Journal of
- the FlagShip/StarShip, SIGS (Special Interest Groups) on the
- Delphi and GEnie telecommunications networks. Permission is
- hereby granted to non-profit organizations only to reprint this
- article or pass it along electronically as long as proper credit
- is given to both the author and the *StarBoard* Journal.
- *********************************************************************
-
- DRAWING IN COMAL 0.14
-
- by Valerie Kramer
-
- *********************************************************************
- [ED. NOTE: This article is perfect for those who lack documentation for
- COMAL. It contains a complete program to draw a picture. This article
- is reprinted by permission from:
- COMAL TODAY
- 6041 Monona Drive
- Madison, WI 53716
- and is copyrighted 1985 by Valerie Kramer.]
- *********************************************************************
-
- A friend of mine got me started some time back when he asked for
- help in programming a Keno game in COMAL. Thanks to that project I
- got past the learning curve of COMAL and realized what a treasure
- I had in the language. Well, that same friend has been at it
- again. I suggested he try a simple project by himself: a COMAL
- program to draw a "Kilroy" picture. You know, a brick wall with a
- simple face peering over the top. He tried, but I found that he
- really didn't have the first idea where to start. So, for those of
- you in the same boat, here is how you can draw Kilroy or anything
- else. I have no artistic talent worth mentioning, so I will leave
- details of composition to your imagination. I want to show what
- the various COMAL graphics statements are, how to use them, and
- how to produce the simple geometric patterns from which many
- pictures are made.
-
- The COMAL graphic commands are shown in the list below, grouped by
- function. We will see many of them in this article. You may wish
- to look up those we don't use. Most of them are pretty simple once
- you have a general idea of what is going on, and I hope you have
- that idea by the end of the article.
-
- SETGRAPHIC SETTEXT
- FULLSCREEN SPLITSCREEN
- BACKGROUND BORDER PENCOLOR
- HIDETURTLE SHOWTURTLE TURTLESIZE
- PENDOWN PENUP
- DRAWTO MOVETO SETXY
- LEFT RIGHT SETHEADING
- BACK FORWARD
- HOME
- CLEAR
- FRAME
- PLOT FILL
- PLOTTEXT
-
- The first thing you need to do is to get into COMAL. From COMAL
- you must enter graphics mode:
-
- SETGRAPHIC 0
-
- That puts you in the high-res graphics mode. (There is also a
- multi-color mode, SETGRAPHIC 1, which works pretty much the same
- as high-res. Let's save it for another time.) At this point, you
- should see a blank screen with a triangular-shaped turtle in the
- center and a couple of lines across the top of the screen in a
- different color. The large area is your graphic screen. The small
- area at the top is a text area where you can give commands. Let's
- try a couple of commands just for fun. Press the RETURN key after
- each command.
-
- FORWARD 50
- RIGHT 90
- FORWARD 50
- RIGHT 90
- FORWARD 50
- RIGHT 90
- FORWARD 50
-
- Did your turtle draw a box? You can clear your screen and start
- over with the command CLEAR. You can return the turtle to the
- starting position without clearing the screen by using the HOME
- command. Try them now.
-
- HOME
- CLEAR
-
- We can control the turtle with the HIDETURTLE, SHOWTURTLE, and
- TURTLESIZE commands. Try these:
-
- HIDETURTLE
- SHOWTURTLE
- TURTLESIZE 0
- TURTLESIZE 5
- TURTLESIZE 10
-
- Next, let's get a good map of the graphic screen in our mind.
- There are 64,000 distinct points on the screen. They are arranged
- in a rectangle 200 points high by 320 wide. Each point is labeled
- by two numbers. The first number tells how far the point is from
- the left edge, and the second tells how far from the bottom of the
- screen. Thus the lower left point is 0,0 because it is at the left
- edge and on the bottom. The top right point is 319,199. The center
- of the screen is called the "home" position of the turtle. It is
- located at point 160,99.
-
- y 0,199....160,199....319,199
- y ...........................
- y ...........................
- y 0,99.....160,99......319,99
- y ...........................
- y ...........................
- y 0,0......160,0........319,0
-
- xxxxxxxxxxxxxxxxxxxxxxxxxxx
-
- Now that we know how our points are numbered, we can turn on any
- point we want using the PLOT command. PLOT x,y turns on the single
- point located at the specified x,y position. Let's try some and
- get a feel for our screen.
-
- PLOT 160,200
- PLOT 140,99
- PLOT 140,95
- PLOT 10,10
- PLOT 315,195
- PLOT 5,195
- PLOT 317,5
-
- Continue playing until you have a good feel for the screen
- coordinate system.
-
- The next geometric figure is the straight line. From geometry we
- know that two points determine a line. We need a starting and an
- ending point. To draw a line on our screen, we first move to the
- starting point of our line then draw a line to the ending point.
-
- There are a couple ways of doing this. Here are some examples:
-
- A SETXY 23,99
- FORWARD 51
-
- MOVETO 25,99
- DRAWTO 25,150
-
- Or
- SETXY 235,185
- FORWARD 36
-
- MOVETO 235,180
- DRAWTO 270,180
-
- How about lines at angles? Sure!
-
- SETXY 170,150
- SETHEADING 135
- FORWARD 75
-
- MOVETO 160,150
- DRAWTO 210,100
-
- Try some of your own. When you are done, clear the screen with the
- CLEAR command. Note that the SETHEADING command turns the turtle
- to the specified angle where zero degrees is straight up, 90
- degrees is right, etc. Some projects will be more easily drawn
- with MOVETO and DRAWTO while others will do better with SETXY,
- SETHEADING, and FORWARD type commands.
-
- Now let's try for some polygons starting with a triangle. We move
- to the first point, draw to the second, draw to the third, then
- draw to the first again.
-
- MOVETO 140,99
-
- DRAWTO 160,129
- DRAWTO 180,99
- DRAWTO 140,99
-
- I'll leave other straight-lined figures for you to work out on
- your own. You know how to put any kind of a straight line on the
- screen at any place you wish, so you should really have no
- problems.
-
- Since we are going to get into more complicated figures, it's time
- to change our method of operation. Instead of typing in each
- command and watching it execute, we will write a program
- containing the commands. When it is just the way we want it, we
- will RUN it and have our picture drawn for us. This has several
- advantages. We can save our program for repeated use. We can make
- use of loops and other program constructs that are not available
- as direct commands. When we make a goof, we need only correct the
- program. We don't have to type all the other commands over, too.
-
- Let's get out of graphics mode. You can give the command SETTEXT
- or just hit the F1 key. If you type SETGRAPHIC without a number,
- or hit the F3 key you will be back in split screen graphics mode
- and can review your picture. F5 puts you in fullscreen graphics
- mode. You can also change modes with the SPLITSCREEN and
- FULLSCREEN commands, but the function keys are simpler to use. Try
- playing with the them now, then return to text mode (F1).
-
- Since we start our program from text mode, the first thing it
- needs to do is to enter graphics mode. We will not be giving
- commands in graphics mode (our program does that for us), so let's
- use the fullscreen graphics. Finally let's hide the turtle so we
- can see only the points and lines we've drawn. Our program will
- begin like this:
-
- 10 // Comment to identify our program.
- 20 setgraphic 0
- 30 fullscreen
- 40 hideturtle
-
- I haven't said anything about colors yet, but let's set our
- background and border colors. We may need to look up the color
- numbers in the Commodore Programmer's Reference Guide. COMAL uses
- the same color numbers used by BASIC. Black is 0, White is 1, Red
- is 2, Green is 5, Blue is 6, etc.
-
- 50 background 1
- 60 border 5
- 70 clear
-
- The CLEAR command will erase the graphics screen and set it all to
- the color we last specified with the BACKGROUND command. We can
- also set the color of the lines we want drawn. We do this with the
- PENCOLOR statement.
-
- 80 pencolor 6
-
- We're all set now, but what shall we do? Let's draw the square we
- drew earlier in the direct command mode.
-
- 90 forward 50
- 100 right 90
- 110 forward 50
- 120 right 90
- 130 forward 50
- 140 right 90
- 150 forward 50
-
- Now run it. Because we are in program mode, we can make use of
- loop and conditional structures. FOR-ENDFOR loops are particularly
- useful for polygons. Let's improve the square program with a FOR
- loop.
-
- 0010 // improved square program
- 0020 setgraphic 0
- 0030 fullscreen
- 0040 hideturtle
- 0050 background 1
- 0060 border 5
- 0070 clear
- 0080 pencolor 6
- 0090 for side = 1 to 4
- 0100 forward 50
- 0110 right 90
- 0120 endfor side
-
- With a simple change, we can make this program print any polygon.
- Add line 15 and replace lines 90 thru 120 with this:
-
- 0015 input "how many sides? ":number
-
- 0090 //
- 0100 for sides= 1 to number do
- 0110 forward 10
- 0120 right 360/number
- 0130 endfor sides
-
- Try some programs of your own. You might also want to use the LEFT
- and BACK commands. They work like RIGHT and FORWARD but go in the
- other direction.
-
- In order to draw curved lines, we cheat. The COMAL statements
- necessary have already been written for us and are found in the
- Library of Functions and Procedures book/disk set. It includes
- procedures that will draw circles and arcs for us. All we have to
- do is merge the procedures from the library disk into our program
- and call them as needed. The book explains how to call each
- routine.
-
- To merge a library procedure or function with your program you
- write your program making sure that you do not use any line
- numbers greater than 8999. The library routines start at 9000.
- When you are ready, you ENTER the library routine. This will merge
- it from disk and put it at the end of your program. Remember that
- ENTER only works with SEQ files (as created by LISTing a program
- section to disk)!
-
- The library disk is set up so ENTER will work. After the library
- routine is entered, renumber your program to make room for any
- additional routines you may want to merge:
-
- RENUM
-
- If you forget to renumber, the next routine you ENTER will overlay
- all or part of the first one and you will have a real mess.
-
- It's time to start drawing Kilroy. Kilroy consists of a wall of
- bricks (let's keep it simple with only three rows of bricks) with
- Kilroy's head peeking over the wall. For extra credit, you
- ambitious ones can add Kilroy's fingers and nose or extend the
- picture in other ways. For now we need to draw two objects - a
- brick wall, and a head. The brick wall can be seen in several
- ways:
-
- 1. A lot of distinct lines
- 2. A box with two horizontal lines and
- a bunch of vertical ones
- 3. three rows of bricks.
-
- The third alternative is probably the best because it is the most
- general description. We can easily draw a brick. It's just a
- variation of our square program. Next we can learn to draw a row
- of bricks, and finally we can draw three such rows. By abstracting
- the program this way, we will later be able to change the size of
- the brick, the number of bricks in a row, the number of rows, etc.
- With the other two approaches these changes would be very
- difficult.
-
- In fact, to keep things very modular, we will put each of our
- abstractions into its own procedure. Let's write the BRICK PROC:
-
- 310 proc brick(high,wide) closed
- 320 for side:=1 to 2 do
- 330 forward high
- 340 right 90
- 350 forward wide
- 360 right 90
- 370 endfor side
- 380 //
- 390 left 90
- 400 back wide
- 410 right 90
- 420 endproc brick
-
- Notice that we had to use separate FORWARD commands for the two
- adjacent sides since they may not be the same length. The LEFT,
- BACK, RIGHT statements at the end of the proc move the turtle to
- the right end of the brick in position to draw an adjacent brick.
- This will make our procedure to draw a row of bricks very simple:
-
- 440 proc row'of'bricks(count,high,wide) cl
- osed // wrap line
- 450 for i:=1 to count do
- 460 brick(high,wide)
- 470 endfor i
- 480 endproc row'of'bricks
-
- There is only one small problem. Succeeding rows of bricks
- alternate a short and a long brick at the start of the row. We can
- make a second proc for the other row of bricks:
-
- 500 proc other'row'of'bricks(count,high,wi
- de) closed // wrap line
- 510 short:=int(wide/2)
- 520 brick(high,short)
- 530 //
- 540 for i:=1 to count-1 do
- 550 brick(high,wide)
- 560 endfor i
- 570 //
- 580 short:=wide-short
- 590 brick(high,short)
- 600 endproc other'row'of'bricks
-
- We had to be careful in our computations because we don't want to
- end up with one row of bricks shorter than another. We are now
- ready for our wall procedure:
-
- 620 proc brick'wall(x,y,rows,count,high,wi
- de) closed // wrap line
- 630 moveto x,y
- 640 case (rows mod 2) of
- 650 when 0
- 660 for i:=1 to rows/2 do
- 670 row'of'bricks(count,high,wide)
- 680 moveto x,y-(2*i*high)
- 690 other'row'of'bricks(count,high,wide)
- 700 moveto x,y-((2*i+1)*high)
- 710 endfor i
- 720 when 1
- 730 row'of'bricks(count,high,wide)
- 740 moveto x,y-high
- 750 for i:=1 to (rows-1)/2 do
- 760 other'row'of'bricks(count,high,wide)
- 770 moveto x,y-(2*i*high)
- 780 row'of'bricks(count,high,wide)
- 790 moveto x,y-((2*i+1)*high)
- 800 endfor i
- 810 endcase
- 820 endproc brick'wall
-
- Again, we had to be careful because we might call for either an
- even or odd number of bricks. Note that we must also be sure to
- set our position before drawing each row of bricks.
-
- Our main program is very much like it used to be:
-
- 100 // for comal 0.14 - kilroy was here
- 110 // delete "0:c14.kilroy"
- 120 // save "0:c14.kilroy"
- 130 setgraphic 0
- 140 fullscreen
- 150 hideturtle
- 160 background 1
- 170 border 5
- 180 clear
- 190 pencolor 0
- 200 brick'wall(20,80,3,10,10,25)
- 210 arc(160,90,40,0,180) // head
-
- Finally we start tinkering and add the bells and whistles. We add
- eyes and a nose as well as a title for the picture. Here is the
- final version as far as I have taken it. Now it's your turn to
- experiment both with this picture and others of your own creation.
- Good luck and have fun!
-
- 0100 // for comal 0.14 - kilroy was here
- 0110 // delete "0:kilroy"
- 0120 // save "0:kilroy"
- 0130 setgraphic 0
- 0140 fullscreen
- 0150 hideturtle
- 0160 background 1
- 0170 border 5
- 0180 clear
- 0190 pencolor 0
- 0200 brick'wall(20,80,3,10,10,25)
- 0210 arc(160,90,40,0,180) // head
- 0220 pendown
- 0230 moveto 150,115
- 0240 brick(4,4) // eye
- 0250 moveto 170,115
- 0260 brick(4,4) // eye
- 0270 moveto 160,100
- 0280 brick(6,4) // mouth
- 0290 plottext 100,10,"kilroy was here"
- 0300 //
- 0310 proc brick(high,wide) closed
- 0320 for side:=1 to 2 do
- 0330 forward high
- 0340 right 90
- 0350 forward wide
- 0360 right 90
- 0370 endfor side
- 0380 //
- 0390 left 90
- 0400 back wide
- 0410 right 90
- 0420 endproc brick
- 0430 //
- 0440 proc row'of'bricks(count,high,wide) c
- losed // wrap line
- 0450 for i:=1 to count do
- 0460 brick(high,wide)
- 0470 endfor i
- 0480 endproc row'of'bricks
- 0490 //
- 0500 proc other'row'of'bricks(count,high,w
- ide) closed // wrap line
- 0510 short:=int(wide/2)
- 0520 brick(high,short)
- 0530 //
- 0540 for i:=1 to count-1 do
- 0550 brick(high,wide)
- 0560 endfor i
- 0570 //
- 0580 short:=wide-short
- 0590 brick(high,short)
- 0600 endproc other'row'of'bricks
- 0610 //
- 0620 proc brick'wall(x,y,rows,count,high,w
- ide) closed // wrap line
- 0630 moveto x,y
- 0640 case (rows mod 2) of
- 0650 when 0
- 0660 for i:=1 to rows/2 do
- 0670 row'of'bricks(count,high,wide)
- 0680 moveto x,y-(2*i*high)
- 0690 other'row'of'bricks(count,high,wid
- e) // wrap line
- 0700 moveto x,y-((2*i+1)*high)
- 0710 endfor i
- 0720 when 1
- 0730 row'of'bricks(count,high,wide)
- 0740 moveto x,y-high
- 0750 for i:=1 to (rows-1)/2 do
- 0760 other'row'of'bricks(count,high,wid
- e) // wrap line
- 0770 moveto x,y-(2*i*high)
- 0780 row'of'bricks(count,high,wide)
- 0790 moveto x,y-((2*i+1)*high)
- 0800 endfor i
- 0810 endcase
- 0820 endproc brick'wall
- 0830 //
- 0840 proc arc(x,y,r,sa,ca) closed
- 0850 moveto x,y
- 0860 setheading 90-sa
- 0870 penup
- 0880 forward r
- 0890 left 90
- 0900 pendown
- 0910 arcl(r,ca)
- 0920 penup
- 0930 endproc arc
- 0940 //
- 0950 proc arcl(r,ca) closed
- 0960 for i:=1 to ca/10 do
- 0970 left 5
- 0980 forward r*3.14159/18
- 0990 left 5
- 1000 endfor i
- 1010 endproc arcl
-